package com.qd.p2p.web.action.user;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import javax.annotation.Resource;

import com.qdlc.p2p.biz.service.MemberInfosService;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.Result;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;

import com.qd.p2p.adapter.AdaptedRequestHandleService;
import com.qd.p2p.adapter.PlatformInfo;
import com.qd.p2p.adapter.param.QueryP2PBusinessParameter;
import com.qd.p2p.adapter.response.QueryP2PBusinessUserInfoResponse;
import com.qd.p2p.adapter.response.QueryP2PBusinessUserInfoResponse.UserInfo;
import com.qdlc.p2p.biz.service.AdditionalUserCardService;
import com.qdlc.p2p.biz.service.UserIdentifyService;
import com.qdlc.p2p.biz.service.UserService;
import com.qdlc.p2p.biz.service.user.UserMemberRealNameService;
import com.qdlc.p2p.biz.service.user.UserRealNameService;
import com.qdlc.p2p.biz.web.action.BaseAction;
import com.qdlc.p2p.common.constant.Constant;
import com.qdlc.p2p.common.constant.Global;
import com.qdlc.p2p.common.core.ReturnResult;
import com.qdlc.p2p.common.enums.EnumCardType;
import com.qdlc.p2p.common.enums.EnumUploadImgType;
import com.qdlc.p2p.common.exception.BusinessException;
import com.qdlc.p2p.common.exception.UserException;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.common.util.IdCard;
import com.qdlc.p2p.common.util.OrderNoUtil;
import com.qdlc.p2p.dal.common.SystemConfigHelper;
import com.qdlc.p2p.dal.common.SystemConfigHelper.Nid;
import com.qdlc.p2p.dal.dto.MemberInfos;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.dto.UserIdentify;
import com.qdlc.p2p.dal.util.UserUtils;

/**
 * 用户实名认证
 *
 * @author linya
 */
public class UserRealNameAction extends BaseAction<User> {
	private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(UserRealNameAction.class);
	@Resource
	UserRealNameService userRealNameService;

	@Resource
	UserMemberRealNameService userMemberRealNameService;

	@Resource
	UserIdentifyService userIdentifyService;

	@Resource
	UserService userService;
	
	@Resource
	private AdaptedRequestHandleService adaptedRequestHandleService;

	@Resource
	AdditionalUserCardService additionalUserCardService;

	@Resource
	MemberInfosService memberInfosService;
	
	/**
	 * 通用的适配型实名认证（账号绑定）
	 * 如果bindCode存在则进行已有账号绑定，反正新建账号
	 */
	@Action(value = "/tpp/tppAction/realName", interceptorRefs = { @InterceptorRef("session"),
			@InterceptorRef("globalStack") }, results = {
					@Result(name = "result", type = "ftl", location = "/member/tpp/" + Constant.TPP_PACKAGE
							+ "/adapterRealName.html") })
	public String adapterRealName() throws Exception {
		// 检测用户是否登录
		User user = checkUser();

		// 获取请求参数
		// String account = paramString("account");
		String cardId = paramString("cardId");
		String realName = paramString("realName");
		realName = StringUtils.isBlank(realName) ? user.getRealName() : realName;
		cardId = StringUtils.isBlank(cardId) ? user.getCardId() : cardId;
		String returnUrl = SystemConfigHelper.getValue(Nid.WEB_URL) + "/tpp/tppAction/realNameCallBack.html";
		String pageUrl = SystemConfigHelper.getValue(Nid.WEB_URL) + "/member/main.html";
		String msg = checkParams(cardId, realName);
		if (msg == null) {
			User u = userRealNameService.realName(user.getUserId(), cardId, realName);
			if (u != null) {
				PlatformInfo platformInfo = adaptedRequestHandleService.getPlatformInfo();
				request.setAttribute("domain", platformInfo.getDomain());
				request.setAttribute("merchantId", platformInfo.getMerchantId());
				request.setAttribute("terminalId", platformInfo.getTerminalId());
				String xml = String.format(
						"<?xml version='1.0' encoding='UTF-8'?><custody_req>" + "<bf_account>%s</bf_account>"
								+ "<name>%s</name>" + "<id_card>%s</id_card>" + "<user_id>%s</user_id>"
								+ "<return_url>%s</return_url>" + "<page_url>%s</page_url>" + "</custody_req>",
						user.getMobilePhone(), realName, cardId, u.getTppUserCustId(), returnUrl, pageUrl);
				LOG.info(" [实名认证请求xml]: " + xml);
				request.setAttribute("requestParams", xml);
				request.setAttribute("sign", adaptedRequestHandleService.aesEncryptKey16(xml));
				return "result";
			}
			msg = "正在实名中，请等待";
		}
		request.setAttribute("rsmsg", msg);
		return MSG;
	}

	private String checkParams(String cardId, String realName) {
		if (StringUtils.isBlank(cardId)) {
			return "身份证不能为空！";
		}
		if (StringUtils.isBlank(realName)) {
			return "姓名不能为空！";
		}
		// 验证身份证
		IdCard idCard = null;
		try {
			idCard = IdCard.getInstance(cardId);
		} catch (Exception e) {
			return "身份证无效!";
		}
		if ((idCard != null) && (idCard.getIdType() == IdCard.ID_NUM_V1)) {
			return "不支持一代身份证!";
		}
		if ((idCard != null) && (DateUtil.getLifeFullYear(idCard.getBirthday()) < 18)) {
			return "未满18周岁不能开户!";
		}
		return null;
	}

	@Action(value = "/tpp/tppAction/checkRealName")
	public String checkRealName() throws Exception {// 检测用户是否登录
		User user = checkUser();
		QueryP2PBusinessParameter parameter = new QueryP2PBusinessParameter();
		parameter.setType(8);
		parameter.setOrderId(user.getTppUserCustId());
		QueryP2PBusinessUserInfoResponse resp = adaptedRequestHandleService.queryP2PBusinessUserInfo(parameter);
		String msg = "操作失敗";
		if (resp.isSuccess()) {
			List<UserInfo> infos = resp.getResult();
			UserIdentify sessionUserIdentify = userIdentifyService.findByUserId(user.getUserId());
			if ((infos != null) && (infos.size() > 0)) {
				UserInfo info = infos.get(0);
				// 1 正常 0未授权 -1已注销
				if (info.getState() == 1) {
					if (sessionUserIdentify.getRealNameStatus() == 2) {
						userIdentifyService.modifyRealnameStatus(user.getUserId(), 1, 2);
						userIdentifyService.modifyTppMobilePhoneStatus(user.getUserId(), 1, 2);
						sessionUserIdentify.setMobilePhoneStatus(1);
						sessionUserIdentify.setTppMobilePhoneStatus(1);
						//实名认证送"酒"卡
				        additionalUserCardService.giveCard(user, EnumCardType.WINE_WIND_CARD.getType());
						session.put(Constant.SESSION_USER_IDENTIFY, sessionUserIdentify);
					}
					msg = "实名成功";
				} else if (info.getState() == 0) {
					msg = "实名未授权";
				} else if (info.getState() == -1) {
					msg = "账户已经被注销";
				}
			} else {
				if (sessionUserIdentify.getRealNameStatus() == 2) {
					userIdentifyService.modifyRealnameStatus(user.getUserId(), 0, 2);
					userIdentifyService.modifyTppMobilePhoneStatus(user.getUserId(), 0, 2);
					sessionUserIdentify.setMobilePhoneStatus(0);
					sessionUserIdentify.setTppMobilePhoneStatus(0);
				}
				session.put(Constant.SESSION_USER_IDENTIFY, sessionUserIdentify);
				msg = "账户未绑定";
			}
		}
		request.setAttribute("rsmsg", msg);
		return MSG;

	}

	@Action(value = "/tpp/tppAction/realNameCallBack")
	public void adapterRealNameCallBack() throws Exception {
		PlatformInfo platformInfo = adaptedRequestHandleService.getPlatformInfo();

		String result = paramString("result");
		String sign = paramString("sign");
		String tppId = null;
		String code = null;
		String successCode = "success";
		LOG.info(" [实名认证回调] result : " + result + "  sign : " + sign);
		if ("baofoo".equalsIgnoreCase(platformInfo.getName())) {
			// TODO 存在判读的隐患
			successCode = "CSD000";
			if (StringUtils.isNotBlank(result) && StringUtils.isNotBlank(sign)
					&& sign.equals(adaptedRequestHandleService.signMd5(result))) {
				InputStream is = new ByteArrayInputStream(result.getBytes());
				SAXReader sax = new SAXReader();
				try {
					Document xmlDoc = sax.read(is);
					Element root = xmlDoc.getRootElement();
					Node userIdNode = root.selectSingleNode("//user_id");
					Node codeNode = root.selectSingleNode("//code");
					tppId = userIdNode.getText();
					code = codeNode.getText();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		if ((code != null)) {
			if ((tppId != null) && code.equals(successCode)) {
				User user = userService.findByTppId(tppId);
				if (user != null) {
					userIdentifyService.modifyRealnameStatus(user.getUserId(), 1, 2);
					userIdentifyService.modifyTppMobilePhoneStatus(user.getUserId(), 1, 2);
					//实名认证送"酒"卡
			        additionalUserCardService.giveCard(user, EnumCardType.WINE_WIND_CARD.getType());
					printWebSuccess();
				}
			}
		}
		printWebResult("实名认证失败", false);
	}

	@Action(value = "/tpp/tppAction/sendRealNameCode", interceptorRefs = { @InterceptorRef("session"),
			@InterceptorRef("globalStack") })
	public void sendRealNameCode() throws Exception {
		// 检测用户是否登录
		User user = checkUser();
		if (org.apache.commons.lang3.StringUtils.isBlank(user.getTppUserCustId())) {
			ReturnResult result = userRealNameService.sendRealNameCode(user.getMobilePhone());
			printWebResult(result.getErrorInfo(), result.isSuccess());
		} else {
			printWebResult("您已经实名认证", false);
		}
	}

	/**
	 * 检测Session用户
	 */
	private User checkUser() {
		User user = getSessionUser();
		if (user == null) {
			throw new UserException("请先登录！", BusinessException.TYPE_JSON);
		}
		return user;
	}

	/**
	 * 企业用户开户
	 *
	 * @throws Exception
	 */
	@Action(value = "/tpp/tppAction/auditMemberInfos", interceptorRefs = { @InterceptorRef("session"),
			@InterceptorRef("globalStack") }, results = {
					@Result(name = "result", type = "ftl", location = "/member/tpp/" + Constant.TPP_PACKAGE
							+ "/realNameForMember.html") })
	public String realNameForMember() throws Exception {

		// 检测用户是否登录
		User user = checkUser();

		// 检测请求参数
		MemberInfos member = checkBFMemberInfosParams(user);

		Global.setIP(request);
		String tppUserCustId = UserUtils.getUserTppCustId(user.getUserId());
		if (StringUtils.isBlank(tppUserCustId)) {
			tppUserCustId = OrderNoUtil.getInstance().getSerialNumber();
			user.setTppUserCustId(tppUserCustId);
		}
		member.setIdentityId(tppUserCustId);
		member.setIdentityType("UID");
		member.setUserId(user.getUserId());
		// 开始开户流程
		// ReturnResult result = userMemberRealNameService.realName(user, member);
		userMemberRealNameService.saveMemberInfos(user, member);
		// printWebResult(result.getErrorInfo(), result.isSuccess());

		PlatformInfo platformInfo = adaptedRequestHandleService.getPlatformInfo();
		request.setAttribute("domain", platformInfo.getDomain());
		request.setAttribute("merchantId", platformInfo.getMerchantId());
		request.setAttribute("terminalId", platformInfo.getTerminalId());
		String xml = String.format(
				"<?xml version='1.0' encoding='UTF-8'?><custody_req>" + "<bf_account>%s</bf_account>"
						+ "<user_id>%s</user_id>" + "<name>%s</name>" + "<id_card>%s</id_card>"
						+ "<enterprise_name>%s</enterprise_name>" + "<license>%s</license>" + "<mobile>%s</mobile>"
						+ "<return_url>%s</return_url>" + "</custody_req>",
				member.getEmail(), tppUserCustId, member.getLegalPerson(), member.getCertNo(), member.getCompanyName(),
				member.getLicenseNo(), member.getLegalPersonPhone(), paramString("returnUrl"));
		LOG.info(" [企业开户请求xml]: " + xml);
		request.setAttribute("requestParams", xml);
		request.setAttribute("sign", adaptedRequestHandleService.aesEncryptKey16(xml));
		return "result";
	}

	@Action(value = "/tpp/tppAction/auditMemberCallBack")
	public void tppAuthCallBack() throws Exception {
		PlatformInfo platformInfo = adaptedRequestHandleService.getPlatformInfo();

		String result = paramString("result");
		String sign = paramString("sign");
		String tppId = null;
		String code = null;
		String successCode = "success";
		LOG.info(" 企业开户回调] result : " + result + "  sign : " + sign);
		if ("baofoo".equalsIgnoreCase(platformInfo.getName())) {
			// TODO 存在判读的隐患
			successCode = "CSD000";
			if (StringUtils.isNotBlank(result) && StringUtils.isNotBlank(sign)
					&& sign.equals(adaptedRequestHandleService.signMd5(result))) {
				InputStream is = new ByteArrayInputStream(result.getBytes());
				SAXReader sax = new SAXReader();
				try {
					Document xmlDoc = sax.read(is);
					Element root = xmlDoc.getRootElement();
					Node userIdNode = root.selectSingleNode("//user_id");
					Node codeNode = root.selectSingleNode("//code");
					tppId = userIdNode.getText();
					code = codeNode.getText();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		if ((code != null)) {
			if ((tppId != null) && code.equals(successCode)) {
				User user = userService.findByTppId(tppId);
				MemberInfos memberInfos = memberInfosService.findByIdentityId(tppId);
				user.setRealName(memberInfos.getLegalPerson());
				user.setCardId(memberInfos.getCertNo());
				userService.update(user);
				userMemberRealNameService.updateStatusByTppId(1, null, tppId);
				printWebSuccess();
			} else if (tppId != null) {
				userMemberRealNameService.updateStatusByTppId(2, "失败", tppId);
			}
		}
		printWebResult("实名认证失败", false);
	}

	private MemberInfos checkBFMemberInfosParams(User user) {

		// 联系Email
		String email = paramString("email");
		// 企业法人
		String legalPerson = paramString("legalPerson");
		// 企业名称
		String companyName = paramString("companyName");
		// 法人证件号码
		String certNo = paramString("certNo");
		// 证件类型
		String certType = "IC";
		// 执照号
		String licenseNo = paramString("licenseNo");
		// 法人手机号码
		String legalPersonPhone = paramString("legalPersonPhone");
		// 必须输入校验
		if (StringUtils.isBlank(email)) {
			throw new UserException("联系Email不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(companyName)) {
			throw new UserException("企业名称不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(legalPerson)) {
			throw new UserException("企业法人不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(certNo)) {
			throw new UserException("法人证件号码不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(licenseNo)) {
			throw new UserException("执照号不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(legalPersonPhone)) {
			throw new UserException("法人手机号码不能为空！", BusinessException.TYPE_JSON);
		}
		MemberInfos member = new MemberInfos();
		member.setUserId(user.getUserId());
		member.setCompanyName(companyName);
		member.setLicenseNo(licenseNo);
		member.setEmail(email);
		member.setLegalPerson(legalPerson);
		member.setCertNo(certNo);
		member.setCertType(certType);
		member.setLegalPersonPhone(legalPersonPhone);
		// userMemberRealNameService.saveMemberInfos(user, member);
		return member;
	}

	/**
	 * 检测请求参数
	 */
	private MemberInfos checkMemberInfosParams(User user) {

		// 企业名称
		String companyName = paramString("companyName");
		// 企业网址
		String website = paramString("website");
		// 地址
		String address = paramString("address");
		// 执照号
		String licenseNo = paramString("licenseNo");
		// 营业执照所在地
		String licenseAddress = paramString("licenseAddress");
		// 执照过期日（营业期限）
		String licenseExpireDate = paramString("licenseExpireDate");
		// 营业范围
		String businessScope = paramString("businessScope");
		// 联系电话
		String telephone = paramString("telephone");
		// 联系Email
		String email = paramString("email");
		// 组织机构代码
		String organizationNo = paramString("organizationNo");
		// 企业简介
		String summary = paramString("summary");
		// 企业法人
		String legalPerson = paramString("legalPerson");
		// 法人证件号码
		String certNo = paramString("certNo");
		// 证件类型
		String certType = paramString("certType");
		// 法人手机号码
		String legalPersonPhone = paramString("legalPersonPhone");
		// 银行编号
		String bankCode = paramString("bankCode");
		// 银行卡号
		String bankAccountNo = paramString("bankAccountNo");
		// 卡类型
		String cardType = paramString("cardType");
		// 卡属性
		String cardAttribute = paramString("cardAttribute");
		// 开户行省份
		String province = paramString("province");
		// 开户行城市
		String city = paramString("city");
		// 支行名称
		String bankBranch = paramString("bankBranch");
		// 文件摘要类型
		String digestType = paramString("digestType");
		// 企业资质文件
		String file = paramString("file");
		// 企业资质文件名称
		String mfileName = paramString("mfileName");

		// 必须输入校验
		if (StringUtils.isBlank(companyName)) {
			throw new UserException("企业名称不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(website)) {
			throw new UserException("企业网址不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(address)) {
			throw new UserException("企业地址不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(licenseNo)) {
			throw new UserException("执照号不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(licenseAddress)) {
			throw new UserException("营业执照所在地不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(licenseExpireDate)) {
			throw new UserException("执照过期日（营业期限）不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(businessScope)) {
			throw new UserException("营业范围不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(telephone)) {
			throw new UserException("联系电话不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(email)) {
			throw new UserException("联系Email不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(organizationNo)) {
			throw new UserException("组织机构代码不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(summary)) {
			throw new UserException("企业简介不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(legalPerson)) {
			throw new UserException("企业法人不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(certNo)) {
			throw new UserException("法人证件号码不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(certType)) {
			throw new UserException("证件类型不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(legalPersonPhone)) {
			throw new UserException("法人手机号码不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(bankCode)) {
			throw new UserException("银行编号不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(bankAccountNo)) {
			throw new UserException("银行卡号不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(cardType)) {
			throw new UserException("卡类型不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(cardAttribute)) {
			throw new UserException("卡属性不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(province)) {
			throw new UserException("开户行省份不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(city)) {
			throw new UserException("开户行城市不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(bankBranch)) {
			throw new UserException("支行名称不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(digestType)) {
			throw new UserException("文件摘要类型不能为空！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(file)) {
			throw new UserException("请上传企业资质文件！", BusinessException.TYPE_JSON);
		}
		if (StringUtils.isBlank(mfileName)) {
			throw new UserException("企业资质文件有误！", BusinessException.TYPE_JSON);
		}

		// 上传企业资质文件到平台图片服务器
		String picPath = null;
		boolean pathException = false;
		try {
			picPath = imgUploadToWeb(EnumUploadImgType.PAY.getValue(), mfileName);
		} catch (IOException e) {
			pathException = true;
		}
		if (pathException || (picPath == null) || "error".equals(picPath)) {
			throw new UserException("上传企业资质文件有误", BusinessException.TYPE_JSON);
		}

		user.setEmail(email);
		user.setCardId(certNo);
		user.setRealName(legalPerson);

		MemberInfos member = new MemberInfos();
		member.setUserId(user.getUserId());
		member.setCompanyName(companyName);
		member.setWebsite(website);
		member.setAddress(address);
		member.setLicenseNo(licenseNo);
		member.setLicenseAddress(licenseAddress);
		member.setLicenseExpireDate(DateUtil.valueOf(licenseExpireDate));
		member.setBusinessScope(businessScope);
		member.setTelephone(telephone);
		member.setEmail(email);
		member.setOrganizationNo(organizationNo);
		member.setSummary(summary);
		member.setLegalPerson(legalPerson);
		member.setCertNo(certNo);
		member.setCertType(certType);
		member.setLegalPersonPhone(legalPersonPhone);
		member.setBankCode(bankCode);
		member.setBankAccountNo(bankAccountNo);
		member.setCardType(cardType);
		member.setCardAttribute(cardAttribute);
		member.setProvince(province);
		member.setCity(city);
		member.setBankBranch(bankBranch);
		member.setDigestType(digestType);
		member.setFilePath(picPath);
		member.setFileName(mfileName + ".zip");

		return member;
	}
}
